/**
 * Copyright 2010 The Apache Software Foundation
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.hadoop.hbase.util;

/**
 * Utility for Strings.
 */
public class Strings {
	public final static String DEFAULT_SEPARATOR = "=";
	public final static String DEFAULT_KEYVALUE_SEPARATOR = ", ";

	/**
	 * Append to a StringBuilder a key/value.
	 * Uses default separators.
	 * @param sb StringBuilder to use
	 * @param key Key to append.
	 * @param value Value to append.
	 * @return Passed <code>sb</code> populated with key/value.
	 */
	public static StringBuilder appendKeyValue(final StringBuilder sb, final String key, final Object value) {
		return appendKeyValue(sb, key, value, DEFAULT_SEPARATOR, DEFAULT_KEYVALUE_SEPARATOR);
	}

	/**
	 * Append to a StringBuilder a key/value.
	 * Uses default separators.
	 * @param sb StringBuilder to use
	 * @param key Key to append.
	 * @param value Value to append.
	 * @param separator Value to use between key and value.
	 * @param keyValueSeparator Value to use between key/value sets.
	 * @return Passed <code>sb</code> populated with key/value.
	 */
	public static StringBuilder appendKeyValue(final StringBuilder sb, final String key, final Object value,
			final String separator, final String keyValueSeparator) {
		if (sb.length() > 0) {
			sb.append(keyValueSeparator);
		}
		return sb.append(key).append(separator).append(value);
	}

	/**
	 * Given a PTR string generated via reverse DNS lookup, return everything
	 * except the trailing period. Example for host.example.com., return
	 * host.example.com
	 * @param dnPtr a domain name pointer (PTR) string.
	 * @return Sanitized hostname with last period stripped off.
	 *
	 */
	public static String domainNamePointerToHostName(String dnPtr) {
		if (dnPtr == null)
			return null;
		return dnPtr.endsWith(".") ? dnPtr.substring(0, dnPtr.length() - 1) : dnPtr;
	}

	// Abbreviating
	//-----------------------------------------------------------------------
	/**
	 * <p>Abbreviates a String using ellipses. This will turn
	 * "Now is the time for all good men" into "Now is the time for..."</p>
	 *
	 * <p>Specifically:
	 * <ul>
	 *   <li>If <code>str</code> is less than <code>maxWidth</code> characters
	 *       long, return it.</li>
	 *   <li>Else abbreviate it to <code>(substring(str, 0, max-3) + "...")</code>.</li>
	 *   <li>If <code>maxWidth</code> is less than <code>4</code>, throw an
	 *       <code>IllegalArgumentException</code>.</li>
	 *   <li>In no case will it return a String of length greater than
	 *       <code>maxWidth</code>.</li>
	 * </ul>
	 * </p>
	 *
	 * <pre>
	 * StringUtils.abbreviate(null, *)      = null
	 * StringUtils.abbreviate("", 4)        = ""
	 * StringUtils.abbreviate("abcdefg", 6) = "abc..."
	 * StringUtils.abbreviate("abcdefg", 7) = "abcdefg"
	 * StringUtils.abbreviate("abcdefg", 8) = "abcdefg"
	 * StringUtils.abbreviate("abcdefg", 4) = "a..."
	 * StringUtils.abbreviate("abcdefg", 3) = IllegalArgumentException
	 * </pre>
	 *
	 * @param str  the String to check, may be null
	 * @param maxWidth  maximum length of result String, must be at least 4
	 * @return abbreviated String, <code>null</code> if null String input
	 * @throws IllegalArgumentException if the width is too small
	 * @since 2.0
	 */
	public static String abbreviate(String str, int maxWidth) {
		return abbreviate(str, 0, maxWidth);
	}

	/**
	 * <p>Abbreviates a String using ellipses. This will turn
	 * "Now is the time for all good men" into "...is the time for..."</p>
	 *
	 * <p>Works like <code>abbreviate(String, int)</code>, but allows you to specify
	 * a "left edge" offset.  Note that this left edge is not necessarily going to
	 * be the leftmost character in the result, or the first character following the
	 * ellipses, but it will appear somewhere in the result.
	 *
	 * <p>In no case will it return a String of length greater than
	 * <code>maxWidth</code>.</p>
	 *
	 * <pre>
	 * StringUtils.abbreviate(null, *, *)                = null
	 * StringUtils.abbreviate("", 0, 4)                  = ""
	 * StringUtils.abbreviate("abcdefghijklmno", -1, 10) = "abcdefg..."
	 * StringUtils.abbreviate("abcdefghijklmno", 0, 10)  = "abcdefg..."
	 * StringUtils.abbreviate("abcdefghijklmno", 1, 10)  = "abcdefg..."
	 * StringUtils.abbreviate("abcdefghijklmno", 4, 10)  = "abcdefg..."
	 * StringUtils.abbreviate("abcdefghijklmno", 5, 10)  = "...fghi..."
	 * StringUtils.abbreviate("abcdefghijklmno", 6, 10)  = "...ghij..."
	 * StringUtils.abbreviate("abcdefghijklmno", 8, 10)  = "...ijklmno"
	 * StringUtils.abbreviate("abcdefghijklmno", 10, 10) = "...ijklmno"
	 * StringUtils.abbreviate("abcdefghijklmno", 12, 10) = "...ijklmno"
	 * StringUtils.abbreviate("abcdefghij", 0, 3)        = IllegalArgumentException
	 * StringUtils.abbreviate("abcdefghij", 5, 6)        = IllegalArgumentException
	 * </pre>
	 *
	 * @param str  the String to check, may be null
	 * @param offset  left edge of source String
	 * @param maxWidth  maximum length of result String, must be at least 4
	 * @return abbreviated String, <code>null</code> if null String input
	 * @throws IllegalArgumentException if the width is too small
	 * @since 2.0
	 */
	public static String abbreviate(String str, int offset, int maxWidth) {
		if (str == null) {
			return null;
		}
		if (maxWidth < 4) {
			throw new IllegalArgumentException("Minimum abbreviation width is 4");
		}
		if (str.length() <= maxWidth) {
			return str;
		}
		if (offset > str.length()) {
			offset = str.length();
		}
		if ((str.length() - offset) < (maxWidth - 3)) {
			offset = str.length() - (maxWidth - 3);
		}
		if (offset <= 4) {
			return str.substring(0, maxWidth - 3) + "...";
		}
		if (maxWidth < 7) {
			throw new IllegalArgumentException("Minimum abbreviation width with offset is 7");
		}
		if ((offset + (maxWidth - 3)) < str.length()) {
			return "..." + abbreviate(str.substring(offset), maxWidth - 3);
		}
		return "..." + str.substring(str.length() - (maxWidth - 3));
	}
}
